import { ref, Ref, unref, toRefs, reactive, nextTick, onMounted } from 'vue'
import { PaginationProps as Pagination } from 'ant-design-vue'
import { BasicTableColumn, BasicPageParams } from '@/components/TableList'
import { useI18n } from '@/locales/useI18n'
import { useResponse } from '@/hooks/web/useResponse'

const { t } = useI18n()

interface PaginationProps extends Pagination {
  current: number
  pageSize: number
  total: number
  pageSizeOptions: string[]
  showTotal: (total: number) => string
}

interface UseTableGridType<T = any, K = any> {
  columns: BasicTableColumn<T>[]
  api: PromiseFn
  searchParams?: K
  isMounted?: Boolean
  basicTableInstance?: Ref
}

interface tableListStateType<T = any> {
  basicColumns: BasicTableColumn<T>[]
  dataSource: Ref<Array<Recordable>>
  pagination: PaginationProps
}

interface ReturnMethods {
  getDataList: () => void
  getTableSelection: () => Recordable
  setPagination: (val: Partial<PaginationProps>) => void
  clearTableSelection: () => void
  onChangePage: (val: PaginationProps) => void
}

export type UseTableGridReturnType<T = any> = [
  tableListStateType<T>,
  ReturnMethods
]

const defaultOptions: UseTableGridType = {
  columns: [],
  searchParams: {},
  api: (): Promise<any> => Promise.reject(),
  isMounted: true,
  basicTableInstance: undefined
}

const setColumnsData = function <T = any>(
  data: BasicTableColumn<T>[]
): BasicTableColumn<T>[] {
  return data.map((item: BasicTableColumn<T>, index) => {
    item.fixed = false
    item.checked = true
    item.align = 'center'
    item.rank = index
    return item
  })
}

export function useTableGrid<T = any, K = any>(
  options: Partial<UseTableGridType<T, K>>
): UseTableGridReturnType<T> {
  const {
    columns,
    searchParams,
    api,
    isMounted,
    basicTableInstance
  }: UseTableGridType<T, K> = {
    ...defaultOptions,
    ...options
  }
  const basicColumns: BasicTableColumn<T>[] = setColumnsData<T>(columns)
  const dataSource = ref<Array<Recordable>>([])
  const pagination = reactive<PaginationProps>({
    current: 1,
    pageSize: 10,
    total: 0,
    showSizeChanger: true,
    pageSizeOptions: ['10', '20', '30'],
    showTotal: (total: number) =>
      `${t('system.pagination.start')} ${total} ${t('system.pagination.end')}`
  })
  const { current, pageSize, total } = toRefs(pagination)

  onMounted(() => {
    isMounted && getDataList()
  })

  const setPagination = (val: Partial<PaginationProps>) => {
    Object.assign(pagination, val)
  }

  const setTableData = (res: Recordable) => {
    dataSource.value = res.data
    total.value = res.total
  }

  const getDataList = () => {
    const params: BasicPageParams & K = {
      pageNum: current.value,
      pageSize: pageSize.value,
      ...searchParams
    }
    try {
      api(params)
        .then((res: any) =>
          useResponse(res, {
            error: t('system.api.apiRequestFailed')
          })
        )
        .then(setTableData)
    } catch (err) {}
  }

  const getTableSelection = async () => {
    return !basicTableInstance
      ? undefined
      : nextTick(() => unref(unref(basicTableInstance).getTableSelection()))
  }

  const clearTableSelection = async () => {
    return !basicTableInstance
      ? undefined
      : nextTick(() => unref(unref(basicTableInstance).clearTableSelection()))
  }

  const onChangePage = (val: PaginationProps) => {
    setPagination(val)
    getDataList()
  }

  return [
    { basicColumns, dataSource, pagination },
    {
      getDataList,
      getTableSelection,
      setPagination,
      clearTableSelection,
      onChangePage
    }
  ]
}

export default useTableGrid